--- 2.6.24.3.base/drivers/md/dm.c	2008-02-25 16:20:20.000000000 -0800
+++ 2.6.24.3/drivers/md/dm.c	2008-03-16 01:29:19.000000000 -0700
@@ -1023,7 +1023,7 @@ static struct mapped_device *alloc_dev(i
 	if (!md->tio_pool)
 		goto bad3;
 
-	md->bs = bioset_create(16, 16);
+	md->bs = bioset_create(16);
 	if (!md->bs)
 		goto bad_no_bioset;
 
--- 2.6.24.3.base/drivers/md/dm-crypt.c	2008-02-25 16:20:20.000000000 -0800
+++ 2.6.24.3/drivers/md/dm-crypt.c	2008-03-16 01:29:19.000000000 -0700
@@ -847,7 +847,7 @@ static int crypt_ctr(struct dm_target *t
 		goto bad_page_pool;
 	}
 
-	cc->bs = bioset_create(MIN_IOS, MIN_IOS);
+	cc->bs = bioset_create(MIN_IOS);
 	if (!cc->bs) {
 		ti->error = "Cannot allocate crypt bioset";
 		goto bad_bs;
--- 2.6.24.3.base/drivers/md/dm-io.c	2008-02-25 16:20:20.000000000 -0800
+++ 2.6.24.3/drivers/md/dm-io.c	2008-03-16 01:29:19.000000000 -0700
@@ -55,7 +55,7 @@ struct dm_io_client *dm_io_client_create
 	if (!client->pool)
 		goto bad;
 
-	client->bios = bioset_create(16, 16);
+	client->bios = bioset_create(16);
 	if (!client->bios)
 		goto bad;
 
--- 2.6.24.3.base/fs/bio.c	2008-02-25 16:20:20.000000000 -0800
+++ 2.6.24.3/fs/bio.c	2008-03-16 01:45:07.000000000 -0700
@@ -29,10 +29,7 @@
 #include <scsi/sg.h>		/* for struct sg_iovec */
 
 #define BIO_POOL_SIZE 2
-
-static struct kmem_cache *bio_slab __read_mostly;
-
-#define BIOVEC_NR_POOLS 6
+#define BIO_NR_POOLS 6
 
 /*
  * a small number of entries is fine, not going to be performance critical.
@@ -41,7 +38,7 @@ static struct kmem_cache *bio_slab __rea
 #define BIO_SPLIT_ENTRIES 2
 mempool_t *bio_split_pool __read_mostly;
 
-struct biovec_slab {
+struct bio_slab {
 	int nr_vecs;
 	char *name; 
 	struct kmem_cache *slab;
@@ -53,71 +50,33 @@ struct biovec_slab {
  * unsigned short
  */
 
-#define BV(x) { .nr_vecs = x, .name = "biovec-"__stringify(x) }
-static struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] __read_mostly = {
+#define BV(x) { .nr_vecs = x, .name = "bio-"__stringify(x) }
+static struct bio_slab bio_slabs[BIO_NR_POOLS] __read_mostly = {
 	BV(1), BV(4), BV(16), BV(64), BV(128), BV(BIO_MAX_PAGES),
 };
 #undef BV
 
 /*
  * bio_set is used to allow other portions of the IO system to
- * allocate their own private memory pools for bio and iovec structures.
- * These memory pools in turn all allocate from the bio_slab
- * and the bvec_slabs[].
+ * allocate their own private memory pools for bio structures.
+ * These memory pools in turn all allocate from the bio_slabs[].
  */
 struct bio_set {
-	mempool_t *bio_pool;
-	mempool_t *bvec_pools[BIOVEC_NR_POOLS];
+	mempool_t *bio_pools[BIO_NR_POOLS];
 };
 
 /*
- * fs_bio_set is the bio_set containing bio and iovec memory pools used by
+ * fs_bio_set is the bio_set containing bio memory pools used by
  * IO code that does not need private memory pools.
  */
 static struct bio_set *fs_bio_set;
 
-static inline struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned long *idx, struct bio_set *bs)
-{
-	struct bio_vec *bvl;
-
-	/*
-	 * see comment near bvec_array define!
-	 */
-	switch (nr) {
-		case   1        : *idx = 0; break;
-		case   2 ...   4: *idx = 1; break;
-		case   5 ...  16: *idx = 2; break;
-		case  17 ...  64: *idx = 3; break;
-		case  65 ... 128: *idx = 4; break;
-		case 129 ... BIO_MAX_PAGES: *idx = 5; break;
-		default:
-			return NULL;
-	}
-	/*
-	 * idx now points to the pool we want to allocate from
-	 */
-
-	bvl = mempool_alloc(bs->bvec_pools[*idx], gfp_mask);
-	if (bvl) {
-		struct biovec_slab *bp = bvec_slabs + *idx;
-
-		memset(bvl, 0, bp->nr_vecs * sizeof(struct bio_vec));
-	}
-
-	return bvl;
-}
-
 void bio_free(struct bio *bio, struct bio_set *bio_set)
 {
-	if (bio->bi_io_vec) {
-		const int pool_idx = BIO_POOL_IDX(bio);
-
-		BIO_BUG_ON(pool_idx >= BIOVEC_NR_POOLS);
-
-		mempool_free(bio->bi_io_vec, bio_set->bvec_pools[pool_idx]);
-	}
-
-	mempool_free(bio, bio_set->bio_pool);
+	const int pool_idx = BIO_POOL_IDX(bio);
+	BIO_BUG_ON(pool_idx >= BIO_NR_POOLS);
+	BIO_BUG_ON(!bio->bi_io_vec);
+	mempool_free(bio, bio_set->bio_pools[pool_idx]);
 }
 
 /*
@@ -130,9 +89,7 @@ static void bio_fs_destructor(struct bio
 
 void bio_init(struct bio *bio)
 {
-	memset(bio, 0, sizeof(*bio));
-	bio->bi_flags = 1 << BIO_UPTODATE;
-	atomic_set(&bio->bi_cnt, 1);
+	*bio = (struct bio){ .bi_flags = 1 << BIO_UPTODATE, .bi_cnt = ATOMIC_INIT(1) };
 }
 
 /**
@@ -151,27 +108,28 @@ void bio_init(struct bio *bio)
  **/
 struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs)
 {
-	struct bio *bio = mempool_alloc(bs->bio_pool, gfp_mask);
-
-	if (likely(bio)) {
-		struct bio_vec *bvl = NULL;
-
-		bio_init(bio);
-		if (likely(nr_iovecs)) {
-			unsigned long idx = 0; /* shut up gcc */
-
-			bvl = bvec_alloc_bs(gfp_mask, nr_iovecs, &idx, bs);
-			if (unlikely(!bvl)) {
-				mempool_free(bio, bs->bio_pool);
-				bio = NULL;
-				goto out;
-			}
-			bio->bi_flags |= idx << BIO_POOL_OFFSET;
-			bio->bi_max_vecs = bvec_slabs[idx].nr_vecs;
-		}
-		bio->bi_io_vec = bvl;
+	struct bio *bio;
+	unsigned idx;
+	/*
+	 * see comment near bvec_array define!
+	 */
+	switch (nr_iovecs) {
+		case   0 ...   1: idx = 0; break;
+		case   2 ...   4: idx = 1; break;
+		case   5 ...  16: idx = 2; break;
+		case  17 ...  64: idx = 3; break;
+		case  65 ... 128: idx = 4; break;
+		case 129 ... BIO_MAX_PAGES: idx = 5; break;
+		default:
+			return NULL;
 	}
-out:
+	if (!(bio = mempool_alloc(bs->bio_pools[idx], gfp_mask|__GFP_ZERO)))
+		return NULL;
+
+	bio_init(bio);
+	bio->bi_flags |= idx << BIO_POOL_OFFSET;
+	bio->bi_max_vecs = bio_slabs[idx].nr_vecs;
+	bio->bi_io_vec = (void *)bio + sizeof(struct bio);
 	return bio;
 }
 
@@ -1088,87 +1046,54 @@ struct bio_pair *bio_split(struct bio *b
 
 
 /*
- * create memory pools for biovec's in a bio_set.
- * use the global biovec slabs created for general use.
+ * create memory pools for bios in a bio_set.
+ * use the global bio slabs created for general use.
  */
-static int biovec_create_pools(struct bio_set *bs, int pool_entries)
-{
-	int i;
-
-	for (i = 0; i < BIOVEC_NR_POOLS; i++) {
-		struct biovec_slab *bp = bvec_slabs + i;
-		mempool_t **bvp = bs->bvec_pools + i;
-
-		*bvp = mempool_create_slab_pool(pool_entries, bp->slab);
-		if (!*bvp)
-			return -ENOMEM;
-	}
-	return 0;
-}
-
-static void biovec_free_pools(struct bio_set *bs)
+void bioset_free(struct bio_set *bs)
 {
 	int i;
 
-	for (i = 0; i < BIOVEC_NR_POOLS; i++) {
-		mempool_t *bvp = bs->bvec_pools[i];
+	for (i = 0; i < BIO_NR_POOLS; i++) {
+		mempool_t *bvp = bs->bio_pools[i];
 
 		if (bvp)
 			mempool_destroy(bvp);
 	}
-
-}
-
-void bioset_free(struct bio_set *bs)
-{
-	if (bs->bio_pool)
-		mempool_destroy(bs->bio_pool);
-
-	biovec_free_pools(bs);
-
 	kfree(bs);
 }
 
-struct bio_set *bioset_create(int bio_pool_size, int bvec_pool_size)
+struct bio_set *bioset_create(int entries)
 {
 	struct bio_set *bs = kzalloc(sizeof(*bs), GFP_KERNEL);
+	int i;
 
 	if (!bs)
 		return NULL;
 
-	bs->bio_pool = mempool_create_slab_pool(bio_pool_size, bio_slab);
-	if (!bs->bio_pool)
-		goto bad;
-
-	if (!biovec_create_pools(bs, bvec_pool_size))
-		return bs;
-
-bad:
-	bioset_free(bs);
-	return NULL;
+	for (i = 0; i < BIO_NR_POOLS; i++) {
+		mempool_t *p = mempool_create_slab_pool(entries, bio_slabs[i].slab);
+		if (!(bs->bio_pools[i] = p)) {
+			bioset_free(bs);
+			return NULL;
+		}
+	}
+	return bs;
 }
 
-static void __init biovec_init_slabs(void)
+static int __init init_bio(void)
 {
 	int i;
 
-	for (i = 0; i < BIOVEC_NR_POOLS; i++) {
+	for (i = 0; i < BIO_NR_POOLS; i++) {
 		int size;
-		struct biovec_slab *bvs = bvec_slabs + i;
+		struct bio_slab *bvs = bio_slabs + i;
 
-		size = bvs->nr_vecs * sizeof(struct bio_vec);
+		size = bvs->nr_vecs * sizeof(struct bio_vec) + sizeof(struct bio);
 		bvs->slab = kmem_cache_create(bvs->name, size, 0,
                                 SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
 	}
-}
-
-static int __init init_bio(void)
-{
-	bio_slab = KMEM_CACHE(bio, SLAB_HWCACHE_ALIGN|SLAB_PANIC);
-
-	biovec_init_slabs();
 
-	fs_bio_set = bioset_create(BIO_POOL_SIZE, 2);
+	fs_bio_set = bioset_create(BIO_POOL_SIZE);
 	if (!fs_bio_set)
 		panic("bio: can't allocate bios\n");
 
--- 2.6.24.3.base/include/linux/bio.h	2008-02-25 16:20:20.000000000 -0800
+++ 2.6.24.3/include/linux/bio.h	2008-03-16 01:29:19.000000000 -0700
@@ -293,7 +293,7 @@ extern struct bio_pair *bio_split(struct
 extern mempool_t *bio_split_pool;
 extern void bio_pair_release(struct bio_pair *dbio);
 
-extern struct bio_set *bioset_create(int, int);
+extern struct bio_set *bioset_create(int);
 extern void bioset_free(struct bio_set *);
 
 extern struct bio *bio_alloc(gfp_t, int);
